Set up AI agent instruction files for a workspace
-
What you'll see
An AI coding agent opens a Docly workspace and treats it like a conventional project: runs
git init, hunts forpackage.json, writes a broken.doclyover the document it meant to edit and replaces it, reaches for Express-stylereq/resin an endpoint, hardcodes leading-slash paths.The reflex is to write a long
CLAUDE.mdlisting every rule the agent got wrong. That file grows into a second, worse copy of the documentation — one that nobody maintains, that contradicts the real pages within a month, and that still misses whatever the agent runs into next. -
What's actually happening
The instruction file is not where platform knowledge should live. Docly already has developer documentation and a knowledge base; both are maintained, both are public, both are more complete than anything you will retype into a markdown file. An agent that has been handed a summary will trust the summary and stop reading. An agent that has been handed a map will go and read the actual page.
So the file has exactly three jobs:
1. Make the knowledge base mandatory. Every KB entry exists because someone already got that thing wrong — a document replaced by a broken
.doclywrite, one visitor's session data cached and served to everyone, a live site down for forty minutes. Reading it before starting is what prevents the repeat. Reading it again afterwards is what catches the mistake while it is still cheap. This has to be stated as an instruction, not a suggestion, or it gets skipped.2. Map the documentation. An agent cannot look up what it does not know exists. It will not guess that
docly.linkImageexists, or that#/Services.jsondrives scheduled jobs, or thatdocly put --createcreates a new document from the command line. A table of section links solves that at a fraction of the size of explaining any of it.3. Carry only what is genuinely not lookupable. Which workspace this is — production or test — is nowhere in the documentation, because it differs per copy. That, and a pointer to everything else.
Two mechanical facts shape where the files go. The workspace root is a published folder, so a
CLAUDE.mdorAGENTS.mdplaced there returns200and is downloadable by anyone;.claude/returns404, and Claude Code reads./.claude/CLAUDE.mdas project instructions just as happily as./CLAUDE.md. And@-imports are not lazy — an imported file is inlined at session start, every session, so splitting a long file into several buys maintenance, not context. The mechanism that actually defers loading is a skill. -
What to do
The files
<workspace root>/ ├── .claude/ │ ├── CLAUDE.md ← which workspace this is, and its local conventions │ ├── docly.md ← the KB mandate + the documentation map (imported) │ └── skills/ ← long procedures, loaded only when relevant └── <your content> ← all of this is served over HTTPImport the map from
CLAUDE.mdwith a relative path —@docly.md. KeepCLAUDE.mdunder about 120 lines anddocly.mdmostly links.To be unambiguous about which file holds what: the knowledge-base mandate and the documentation map both live in
docly.md.CLAUDE.mdimports it on the first line and carries nothing but workspace facts. Step 1 below is headed “open with the knowledge base” because that is where a session's context begins — an@-import is inlined at session start, so the mandate is in front of the agent either way.Verify once per workspace that nothing leaked to the root. Both of these must return
404:curl -s -o /dev/null -w "%{http_code}\n" https://<your-site>/CLAUDE.md curl -s -o /dev/null -w "%{http_code}\n" https://<your-site>/AGENTS.md1. Open with the knowledge base — as an instruction
Knowledge base: https://developers.docly.net/Guidelines/KB
Before you start a task, read the knowledge base entries covering what you are about to touch. After you finish, check it again against what you actually did. If you discover something the KB does not cover, add an entry — that is the point of it.
Write the address out, not just a link on the words. This block exists to be copied into a markdown file, and an anchor does not survive that copy — the href is dropped, the sentence still reads complete, and the result is an instruction file that orders an agent to read a knowledge base it has no way to find. That has happened: the agent searched the workspace,
.claude/and~/.claude/skills/, found no KB, and proceeded on inference instead.Follow it with a lookup table so the agent knows which entries apply to the task in front of it, rather than being told to read every article. Build that table from the current index rather than copying the one below. The KB grows; a table frozen at the moment of writing goes on looking authoritative while silently failing to route to anything added since. The table below reaches fewer than half the entries that exist today, and the two it is most often needed for — Renaming a schema field does not migrate documents and Unresolved names in hash expressions render empty — are among the ones it misses. It is a worked example of the shape, not content to copy:
Read before you… Entry Touch anything on a live site Work safely on a live site Write any server-side JavaScript Docly JavaScript is not Node Reach for git or a working copy Use a docly CLI working copy instead of git Create a .doclydocumentCreating new docly files Write a .hashpageHash files are cached, Use master pages for shared layout Write paths or links in JS Use tilde paths in JavaScript, Omit file extensions in links Build an API endpoint Reading query and form fields, Organize pages and API endpoints into topic folders Store or expose data Keep private data under the # folder, Path traversal Add or link an image Scale and convert images, Do not build URLs by hand, Restrict and register image sizes Ship static assets Cache-busting bundles with assetUrl Verify a platform behaviour Use a scratch hash file to test Docly functions Never report documented behaviour as a problem
The mandate above has a second half that matters just as much as the reading: an agent must not raise documented platform behaviour with the user as a bug, a risk, or something to "be aware of". This is not a harmless extra. It sends the user off to investigate something the platform settled long ago, buries the real findings in noise, and costs precisely the time the knowledge base exists to save. On a security review it is worse than noise — it puts remediation work on the roadmap for a vulnerability class that does not exist.
State it in the instruction file as an instruction, not a preference:
Before reporting a bug, a vulnerability or a platform limitation, find the KB entry that covers it. If the behaviour is documented, it is not a finding — do not raise it, and do not soften it into a hedge ("if Docly resolves this…", "worth verifying…", "potential risk"). A hedged false alarm costs the user the same investigation as a confident one. If you have already raised it, correct it in one sentence and carry on.
The one that recurs most:
- Path traversal. The filesystem API accepts absolute paths only and rejects
../at the boundary, so concatenating user input into a path is not an exploitable traversal. See Path traversal.
The rule cuts both ways. Behaviour that genuinely is not documented is a finding, and once resolved it belongs in a KB entry — not in the workspace instruction file.
2. Map the documentation
This is the bulk of the file. Copy it as-is — it is the same in every Docly workspace.
Page For Introduction, Getting Started What Docly is: the file system, templates, the first API JavaScript reference The index for everything below About JavaScript, HASH files How HashJS differs from Node; #expr#and#{ }#syntaxFilesystem functions getFile,getFiles,saveJson,linkImage,linkFileOutput functions write,setMime,setHeader,assetUrl,redirect,htmlToPdfNetwork, Mail, Share, Authentication HTTP calls, SMTP/POP3/IMAP, folder shares, JWT and access control String, Array, Math, Date and time, Validation The standard library as Docly implements it Directives MASTER and INCLUDE Examples Working code: custom APIs, websites, binding, security The API folder How #/API/*.jsendpoints work and routeServices #/Services.json, scheduled jobs and eventsThe Root folder, The Folder folder #/Root/assets and#/Folder/listing templatessite.json, Security headers Site config, image size policy, CSP About schemas, The Docly file format What a schema is; the .doclyJSON envelopeCreate schemas Document and folder schemas Templates, Display templates How rendering works; binding a schema to a .hashEditing documents programmatically Required before creating any .doclyfrom outside the UIPackages Reusable components shared across workspaces 3. State the few things that are not written down anywhere
Which workspace this is, and how it is reached. Nothing in the documentation can tell an agent this, because it differs per copy:
## Environment | **Environment** | PRODUCTION — live and public | | **Live URL** | https://example.com | | **Access mode** | docly CLI working copy | | **Staging copy** | Example (test) — iterate there first | | **Promote by** | Copying reviewed files from the test copy |A common Docly setup keeps several working copies of one application, with identical platform rules and completely different consequences for a careless write. If the workspace is a disposable test copy, say so — an agent that knows it will iterate faster and stop asking for confirmation it does not need.
Skills, for procedures
A skill is a folder under
.claude/skills/with aSKILL.mdwhose front matter describes when to use it. Unlike an import, the body stays out of context until the description matches the task — so this is where multi-step procedures belong.--- name: docly-new-document description: Create a new .docly document from outside the Docly UI. Use whenever you need to add a new .docly file rather than edit an existing one. Covers creating it with the docly CLI (put --create or push), the JSON envelope, schema field mapping, and how to recover from a write that did not register. ---Worth having in a Docly workspace:
docly-new-document,docly-images, anddocly-verify.When the documentation is the thing that is wrong
If you work something out that is not written down, it does not belong in your
CLAUDE.md. Platform behaviour goes in a KB entry; a gap or error in a page goes in the page. An instruction file is the wrong place to accumulate knowledge — it is private to one workspace, invisible to everyone else, and nobody reviews it.If you cannot publish to the KB yourself, write the entry as a draft and hand it to someone who can. Many agents have no write access to the documentation site, and the rule above forbids the outcome without naming the alternative — so the knowledge goes to the only surface the agent can write to, which is the instruction file. That is how a
CLAUDE.mdgrows a section on engine behaviour: an agent learned something real, could not publish it, and parked it. Do not park it. Nothing is more permanent, and the next agent will trust the summary and stop reading.Verify before you write the entry. Knowledge inherited from an instruction file is exactly the unmaintained copy this entry warns about, and it is often stale — two of four such claims lifted from one workspace's
CLAUDE.mdturned out to be wrong when measured, one of them backwards. A throwaway page settles it before it reaches the KB: see Use a scratch hash file to test Docly functions.Keeping it current
Everything above describes first-time setup, but the file decays after that on its own. Re-check it against the KB whenever you read the KB for a task. Anything the KB now documents comes out of the instruction file — the entry is the maintained copy, and a local restatement of it can only drift. What should remain is only what no page anywhere can tell an agent: which workspace this is, how it is reached, and its local conventions.
Content written when it genuinely was undocumented is the usual offender, because nothing prompts a re-read once it is in the file. One workspace accumulated thirty lines of engine behaviour and three “working here” bullets this way; by the time anyone checked, every one of the bullets had a KB entry covering it.
Permissions
A small allowlist in
.claude/settings.local.jsonremoves most approval prompts. Keep it stingy on writes: a broadBash(node *)entry on a production workspace defeats the rule it most needs to enforce, since forcing an edit through with shell-escapednode -eis precisely what has taken a live Docly site down before.Say how the agent should change the site
State in one line that changes go through the
doclyCLI, and point at How an AI agent should use the docly CLI rather than restating those rules here. That article is written to be handed to an agent directly and covers what the command reference cannot: that writing is locked until a human opens a folder, that a refusal means stop and ask, and that the site console and system log are where a change is verified. - Path traversal. The filesystem API accepts absolute paths only and rejects
Last reviewed 17 Oct 2026